// 好友列表的Schema定义    
const mongoose = require("./mgdb.js");
const crypto = require('crypto');
const promisify = require("util").promisify;
const {
	DataRls
} = require("../config/class.js");
const {
	isUserOnline,
	getUser,
	getAllUsers
} = require("../db/onlineUsers.js");

// 邮件的Schema定义
// 邮件保存两份，发送者一份，接收者一份
const emailList = new mongoose.Schema({
	sendID: { //发送者id
		type: mongoose.Schema.Types.ObjectId
	}, //接收者id
	receiveID: {
		type: mongoose.Schema.Types.ObjectId
	},
	message: String, //消息文本
	room: String,
	sendType: { //回执执行结果
		type: String,
		//PC是私聊类型，FQUERY是好友请求
		enum: ["PC", "FQUERY", "HINT"],
	}, //发送类型
	time: Date, //发送时间
	notes: String, //请求等类型的显示注释
	result: { //回执执行结果
		type: String,
		enum: ["close", "wait", 'no', 'ok'],
	},
	meta: {
		type: mongoose.Schema.Types.Mixed
	} //元数据，用来存储邮件中的一些额外消息
});

// 邮件列表模板
const emailSchema = new mongoose.Schema({
	ownerId: { // 邮件列表拥有者的用户ID 
		type: mongoose.Schema.Types.ObjectId,
		required: true,
		unique: true // 确保ownerId的唯一性   
	},
	readList: [], // 已读邮件列表，存储已读邮件的id
	emails: [emailList]
});


// 创建模型    
const Email = mongoose.model('Email', emailSchema);

// 根据ownerId创建邮件列表的方法
async function createEmailList(ownerId) {
	try {
		const emailList = new Email({
			ownerId
		});
		await emailList.save();
		return new DataRls(
			emailList ? "邮件列表创建成功" : "邮件列表创建失败",
			emailList,
			Boolean(emailList)
		);
	} catch (error) {
		throw new DataRls(
			"邮件列表创建失败",
			"邮件列表创建失败",
			false,
			error,
		);
	}
}

// 往指定id中添加邮件的方法(传入Email类的实例对象)
// 这个方法需要对其他用户的邮箱进行操作
async function addEmailToList(ownerId, email) {
	try {
		const emailList = await Email.findOne({
			ownerId
		});
		if (!emailList) {
			throw new DataRls(
				"添加邮件对象未找到",
				"添加邮件失败",
				false,
				new Error('添加邮件对象未找到')
			);
		}
		emailList.emails.push(email);
		await emailList.save();

		let addEmail = emailList.emails[emailList.emails.length - 1];

		// 当用户在线的时候，通知用户有新邮件
		if (isUserOnline(ownerId)) {
			getUser(ownerId).sokcet.emit("NewEmail", addEmail);
		}

		return new DataRls(
			emailList ? "添加邮件成功" : "添加邮件失败",
			addEmail,
			Boolean(emailList)
		);
	} catch (error) {
		throw new DataRls(
			"添加邮件失败",
			"添加邮件失败",
			false,
			error
		);
	}
}

// 设置指定用户的邮件的已读列表
async function updateEmailRead(Id, readList) {
	try {
		// 直接使用updateOne方法更新数据库    
		await Email.updateOne({
			_id: Id
		}, {
			$set: {
				readList
			}
		});

		return new DataRls(
			"已读列表修改成功",
			"邮件已读信息已修改",
			true
		);
	} catch (error) {
		throw error;
	}
}


// 获取指定ID的邮件并设置result字段值的方法    
async function updateEmailResult(ownerId, emailId = "", newResult) {
	try {
		const emailList = await Email.findOne({
			ownerId
		});


		if (!emailList) {
			throw new DataRls(
				"指定邮件列表不存在",
				"指定邮件字段设置失败",
				false
			);
		}

		// 查找指定ID的邮件    
		const email = emailList.emails.find((email) => {
			if (email._id.toString() === emailId.toString()) {
				return true;
			}
		});



		if (!email) {
			throw new DataRls(
				"指定邮件查找失败",
				"指定邮件字段设置失败",
				false
			);
		}

		// 查看数据库中，待处理邮件的值，是否为等待处理
		if (email.result != "wait") {
			throw new DataRls(
				"该邮件状态设置失败",
				"该邮件已经为处理状态",
				false
			);
		}


		// 检查新的result字段值是否有效    
		if (!["close", "wait", "no", "ok"].includes(newResult)) {
			throw new DataRls(
				"设置内容并非有效字段",
				"指定邮件字段设置失败",
				false
			);
		}


		// 设置邮件的result字段    
		email.result = newResult;
		await emailList.save();

		// 返回更新后的邮件列表（可选，根据需求调整）    
		return new DataRls(
			'指定邮件字段设置成功',
			email,
			true
		);
	} catch (error) {
		throw error;
	}
}

// 根据id删除邮件列表
async function deleteEmailsByIdList(id, deletList) {
	try {
		// 构造查询条件，找到包含指定_id的文档    
		const query = {
			_id: id
		};

		// 构造$pull操作符的参数，以删除emails数组中所有匹配的邮件ID    
		const pullOperation = {
			$pull: {
				emails: {
					_id: {
						$in: deletList
					} // 使用$in操作符来匹配多个邮件ID    
				}
			}
		};

		// 使用updateOne方法更新文档    
		const result = await Email.updateOne(query, pullOperation);

		// 如果需要，可以返回删除结果给调用者    
		return new DataRls(
			"邮件删除成功",
			result,
			true // 添加结果    
		);;
	} catch (error) {
		// 邮件删除失败!
		throw new DataRls(
			"邮件删除失败",
			"邮件删除过程中失败",
			false, // 添加结果
			error
		);
	}
}


// 查询指定id的所有邮件的方法
async function getEmailsById(Id) {
	try {
		const emailList = await Email.findById(Id);
		console.log(emailList);
		return new DataRls(
			"邮件查询成功",
			emailList,
			true // 添加结果    
		);
	} catch (error) {
		throw new DataRls(
			"邮件查询失败",
			"邮件查询失败", // 返回信息    
			false, // 添加结果  
			error
		);
	}
}

module.exports = {
	Email, //邮件对象
	createEmailList, // 根据ownerId创建邮件列表的方法
	addEmailToList, // 往指定id中添加邮件的方法(传入Email类的实例对象)
	updateEmailRead, // 设置指定用户的邮件的已读列表
	updateEmailResult, // 将指定id中的指定邮件修改result字段的方法
	deleteEmailsByIdList, // 根据id数组删除邮件的方法
	getEmailsById, // 查询指定id的所有邮件的方法
};